﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BasePlatformNet
{
	public class RdmPacketBuilder
	{
		private const int START_CODE = 0xcc;

		private const int SUB_START_CODE = 0x01;

		// 发现灯具
		public byte[] buildDiscBranchPacket(uint packetNum, uint portIndex, uint lowerBoundUid, uint upperBoundUid)
		{
			byte N = 12;							// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			cmdData[0] = START_CODE;				// START_CODE - 0xCC
			cmdData[1] = SUB_START_CODE;			// SUB_START_CODE - 0x01 
			
			cmdData[2] = cmdLength;					// 消息长度

			// byte3 ~ byte8						// 目标 UID

			// byte9 ~ byte14						// 源 UID

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0
			
			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.DISCOVERY_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.DISC_UNIQUE_BRANCH);	// 命令细节
			cmdData[21] = catalog[1];				
			cmdData[22] = catalog[0];

			cmdData[23] = N;														// 参数长度

			// 参数
			byte[] lowerBoundUidBytes = Tools.int2Byte6((int)lowerBoundUid);		// UID下限, 低字节在前高字节在后
			cmdData[24] = lowerBoundUidBytes[5];
			cmdData[25] = lowerBoundUidBytes[4];
			cmdData[26] = lowerBoundUidBytes[3];
			cmdData[27] = lowerBoundUidBytes[2];
			cmdData[28] = lowerBoundUidBytes[1];
			cmdData[29] = lowerBoundUidBytes[0];
			
			byte[] upperBoundUidBytes = Tools.int2Byte6((int)upperBoundUid);		// UID上限, 低字节在前高字节在后
			cmdData[30] = upperBoundUidBytes[5];
			cmdData[31] = upperBoundUidBytes[4];
			cmdData[32] = upperBoundUidBytes[3];
			cmdData[33] = upperBoundUidBytes[2];
			cmdData[34] = upperBoundUidBytes[1];
			cmdData[35] = upperBoundUidBytes[0];

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 静音/取消静音
		public byte[] buildDiscMutePacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid, bool mute)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			cmdData[0] = START_CODE;				// START_CODE - 0xCC
			cmdData[1] = SUB_START_CODE;			// SUB_START_CODE - 0x01 
			
			cmdData[2] = cmdLength;					// 消息长度

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.DISCOVERY_COMMAND;						// 命令编号

			if (mute == true)
			{
				byte[] catalog = Tools.int2Byte2((int)RdmCatalog.DISC_MUTE);		// 命令细节 - 静音
				cmdData[21] = catalog[1];
				cmdData[22] = catalog[0];
			}
			else
			{
				byte[] catalog = Tools.int2Byte2((int)RdmCatalog.DISC_UN_MUTE);		// 命令细节 - 取消静音
				cmdData[21] = catalog[1];
				cmdData[22] = catalog[0];
			}

			cmdData[23] = N;														// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}
		
		// 获取支持的消息指令
		public byte[] buildGetSupportParameterPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.SUPPORTED_PARAMETERS);		// 命令细节 - 获取支持的消息指令
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 获取设备信息
		public byte[] buildGetDeviceInfoPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.DEVICE_INFO);		// 命令细节 - 获取设备信息
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}
	
		// 获取软件版本说明
		public byte[] buildGetSoftwareVersionLabelPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.SOFTWARE_VERSION_LABEL);		// 命令细节 - 获取软件版本说明
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 设置 DMX512 起始地址
		public byte[] buildSetDmxStartAddrPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid, uint dmxStartAddr)
		{
			byte N = 2;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.SET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.DMX_START_ADDRESS);		// 命令细节 - 设置 DMX512 起始地址
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - DMX512 起始地址
			byte[] startAddr = Tools.int2Byte2((int)dmxStartAddr);
			cmdData[24] = catalog[1];
			cmdData[25] = catalog[0];

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}
	
		// 获取 DMX512 起始地址
		public byte[] buildGetDmxStartAddrPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.DMX_START_ADDRESS);		// 命令细节 - 获取 DMX512 起始地址
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}
	
		// 设置设备标记
		public byte[] buildSetDeviceIdPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid, uint deviceId)
		{
			byte N = 1;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.SET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.IDENTIFY_DEVICE);		// 命令细节 - 设置设备标记
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 设置设备标记
			cmdData[24] = (byte)deviceId;

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 获取设备标记
		public byte[] buildGetDeviceIdPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.IDENTIFY_DEVICE);		// 命令细节 - 获取设备标记
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 获取 Label
		public byte[] buildGetDeviceLabelPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.DEVICE_LABEL);		// 命令细节 - 获取 Label
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 获取制造商信息
		public byte[] buildGetManufacturerLabelPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.MANUFACTURER_LABEL);		// 命令细节 - 获取制造商信息
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 获取灯具状态
		public byte[] buildGetLampStatePacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid)
		{
			byte N = 0;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.LAMP_STATE);		// 命令细节 - 获取灯具状态
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 无

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		/*========================================================================================================================*/

		// 获取探头定义
		public byte[] buildGetSensorDefinitionPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid, uint sensorId)
		{
			byte N = 1;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.SENSOR_DEFINITION);		// 命令细节 - 获取探头定义
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 探头编号
			cmdData[24] = (byte)sensorId;

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 获取探测值
		public byte[] buildGetSensorDataPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid, uint sensorId)
		{
			byte N = 1;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.GET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.SENSOR_VALUE);		// 命令细节 - 获取探测值
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 探头编号
			cmdData[24] = (byte)sensorId;

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}

		// 探头记录当前值
		public byte[] buildSetRecordSensorPacket(uint packetNum, uint portIndex, uint targetUid, uint sourceUid, uint sensorId)
		{
			byte N = 1;								// 参数长度（字节数）
			byte cmdLength = (byte)(24 + N);		// 消息长度（字节数）, 从 START_CODE 开始到结束, 不包括 checksum
			byte[] cmdData = new byte[cmdLength + 1];

			// byte3 ~ byte8						// 目标 UID
			byte[] targetUidBytes = Tools.int2Byte6((int)targetUid);
			cmdData[3] = targetUidBytes[5];
			cmdData[4] = targetUidBytes[4];
			cmdData[5] = targetUidBytes[3];
			cmdData[6] = targetUidBytes[2];
			cmdData[7] = targetUidBytes[1];
			cmdData[8] = targetUidBytes[0];

			// byte9 ~ byte14						// 源 UID
			byte[] sourceUidBytes = Tools.int2Byte6((int)sourceUid);
			cmdData[9] = sourceUidBytes[5];
			cmdData[10] = sourceUidBytes[4];
			cmdData[11] = sourceUidBytes[3];
			cmdData[12] = sourceUidBytes[2];
			cmdData[13] = sourceUidBytes[1];
			cmdData[14] = sourceUidBytes[0];

			cmdData[15] = (byte)packetNum;			// 传输号

			/*********************************************************************************/

			cmdData[16] = (byte)portIndex;			// 控制器端口号

			cmdData[17] = 0x0;						// 控制器固定为0

			cmdData[18] = 0x0;						// 分组号，如果终端下面没有组，填0x0000
			cmdData[19] = 0x0;

			cmdData[20] = (byte)RdmCommand.SET_COMMAND;						// 命令编号

			byte[] catalog = Tools.int2Byte2((int)RdmCatalog.RECORD_SENSORS);		// 命令细节 - 探头记录当前值
			cmdData[21] = catalog[1];
			cmdData[22] = catalog[0];

			cmdData[23] = N;												// 参数长度

			// 参数 - 探头编号
			cmdData[24] = (byte)sensorId;

			// 校验和
			byte checksum = 0x0;
			for (int i = 0; i < 24 + N; i++)
			{
				checksum += cmdData[i];
			}
			cmdData[24 + N] = checksum;

			return cmdData;
		}
	}

	public enum RdmCommand
	{
		DISCOVERY_COMMAND = 0x10,
		DISCOVERY_COMMAND_RESPONSE = 0x11,
		GET_COMMAND = 0x20,
		GET_COMMAND_RESPONSE = 0x21,
		SET_COMMAND = 0x30,
		SET_COMMAND_RESPONSE = 0x31
	}

	public enum RdmCatalog
	{
		DISC_UNIQUE_BRANCH = 0x0001,
		DISC_MUTE = 0x0002,
		DISC_UN_MUTE = 0x0003,

		SUPPORTED_PARAMETERS = 0x0050,

		DEVICE_INFO = 0x0060,

		MANUFACTURER_LABEL = 0x0081,
		DEVICE_LABEL = 0x0082,

		SOFTWARE_VERSION_LABEL = 0x00C0,

		DMX_START_ADDRESS = 0x00F0,

		IDENTIFY_DEVICE = 0x1000,

		SENSOR_DEFINITION = 0x0200,
		SENSOR_VALUE = 0x0201,
		RECORD_SENSORS = 0x0202,

		LAMP_STATE = 0x0403
	}
}
